<?php
import('Think.Template.TagLib');
class TagLibPreem extends TagLib{

    protected $_tablePrefix;
    protected $_options;

    public function __construct($tagLib='',$filename=''){
        parent::__construct($tagLib, $filename);
        $this->_tablePrefix=C('DB_PREFIX');
        $this->_options=array();
    }

    public function _arclist($attr,$content) {
        $tag = $this->parseXmlAttr($attr, 'arclist');
        $parseStr='<?php $_dao=D(\'Archive\');$_where=array(); ?>';
        if ($this->checkVarValid($tag,'category') ) {
            $parseStr.='<?php $_catgoryRange='.$this->parseVar($tag['category']).' ;?>';
            if ($this->checkVarValid($tag,'cascade')) {
                $parseStr.='<?php $_categoryCache=GC_Category();?>';
                $parseStr.='<?php $_rootCategory=split(\',\',$_catgoryRange);$_find=false;$_readDepth='.$tag['cascade'].';$_minLevel=$_maxLevel=0; foreach($_categoryCache as $key=>$val){ if(false===$_find){ if( in_array( $key,$_rootCategory) ) { $_find=true;$_minLevel=intval($val[\'level\']);$_maxLevel=$_minLevel+$_readDepth;}}else{ $_curDepth=intval($val[\'level\']);if( $_curDepth<=$_minLevel ) break;$_catgoryRange.=\',\'.$val[\'id\'];} }?>';
            }
            $parseStr.='<?php $_where[]=\' a.category IN ( \'.$_catgoryRange.\' ) \';?>';
        }
        if ($this->checkVarValid($tag,'thumb')) {
            if ('true'===$tag['thumb']) {
                $parseStr.='<?php $_where[]=" a.thumb <>\'\' "; ?>';
            }else{
                $parseStr.='<?php $_where[]=" a.thumb =\'\' "; ?>';
            }
        }
        $parseStr.='<?php $_where[]=\'a.passId<>0\'; (0===count($_where))?$_whereCondition=\'\':$_whereCondition=implode(\' AND \',$_where); ?>';
        if ($this->checkVarValid($tag,'pagevar')) {
            $pageObject='$_'.$tag['pagevar'];
        }else{
            $pageObject='$_p';
        }
        $listRows=null;
        if ($this->checkVarValid($tag,'rows')) {
            $listRows=intval($tag['rows']);
        }
        if(!$listRows) $listRows=10;
        $parseStr.='<?php $_count=$_dao->count(str_replace("a.","",$_whereCondition));if($_count){ '.$pageObject.'=new Page($_count,'.$listRows.'); $_dao->limit('.$pageObject.'->firstRow.\',\'.'.$pageObject.'->listRows);?>';
        $order='a.pubdate desc';
        if ($this->checkVarValid($tag,'order')) {
            $order='a.'.$tag['order'];
        }
         $parseStr.='<?php $_dao->table(\''.$this->_tablePrefix.'archive a\')->join(\''.$this->_tablePrefix.'user u on u.id=a.pubID\')->join(\''.$this->_tablePrefix.'category c on c.id=a.category\')->order(\''.$order.'\');?>';
        $parseStr.='<?php if($_whereCondition){ $_dao->where($_whereCondition); } $_data=$_dao->field(\'a.*,u.id uid,u.realname,u.account,c.typename,c.englishname\')->findAll();foreach($_data as $'.$tag['id'].'){ ?>'.$this->tpl->parse($content).'<?php }} ?>';
        return $parseStr;
    }

    public function _pagebreak($attr,$content){
        $tag=$this->parseXmlAttr($attr, 'pagebreak');
        return '<?php if( isset($_'.$tag['name'].') ){ echo $_'.$tag['name'].'->show(); } ?>';
    }

    public function _dropmenu($attr,$content) {
        $tag=$this->parseXmlAttr($attr, 'dropmenu');
        $parseStr='<?php echo GC_DropMenu(\''.$tag['uriprefix'].'\',';
        if($this->checkVarValid($tag,'pid')){
            $parseStr.='\''.$tag['pid'].'\'';
        }
        return $parseStr.'); ?>';
    }

    public function _category($attr,$content) {
        $tag=$this->parseXmlAttr($attr, 'pagebreak');
        $parseStr='<?php $_categoryCache=GC_Category();?>';
        if ($this->checkVarValid($tag,'id')) {
            $error='';
            if ($this->checkVarValid($tag, 'error')) {
                $error=$this->parseError($tag['error']);
            }
            $parseId=$this->parseVar($tag['id']);
            $this->_options['categoryCache']=$parseId;
            if ($error) {
                $parseStr.='<?php if(false=array_key_exists('.$parseId.',$_categoryCache)){ '.$error.' } ?>';
            }
        }
        $parseStr.='<?php $_cat=$_categoryCache['.$this->_options['categoryCache'].']; ?>';
        $format='';
        if( $this->checkVarValid($tag, 'format') ){
            $format=str_replace(array('#id#','#typename#'),array('".$_cat[\'id\']."','".$_cat[\'typename\']."'),$tag['format']);
        }
        $parseStr.='<?php if(isset($_cat)){ ?>';
        $field=$tag['field'];
        if ( in_array($field,array('id','pid','typename','fullname','name','level','total','typeformat')) ){
            $parseStr.='<?php echo $_cat[\''.$field.'\']; ?>';
        }else if ('ancestor'===$field) {
            $parseStr.='<?php $_ancestor=\'\'; while(true){ $_pid=intval($_cat[\'pid\']);  if(array_key_exists($_pid,$_categoryCache)){ $_cat=$_categoryCache[intval($_cat[\'pid\'])]; $_ancestor="'.$format.'".$_ancestor;  }else{ break;} } echo $_ancestor; ?>';
        }else if ('brother'===$field) {
            $parseStr.='<?php $_curId=$_cat[\'id\'];$_curPid=$_cat[\'pid\'];foreach( $_categoryCache as $_cat){if($_cat[\'pid\']==$_curPid && $_cat[\'id\']!=$_curId){echo "'.$format.'";}}?>';
        }else if ('parent'===$field) {
            $parseStr.='<?php $_pid=$_cat[\'pid\'];if(\'0\'!=$_pid){$_cat=$_categoryCache[$_pid];echo "'.$format.'";}?>';
        }
        return $parseStr.'<?php } ?>';
    }

    public function _article($attr,$content) {
        $tag=$this->parseXmlAttr($attr, 'pagebreak');
        $parseStr='';
        if ($this->checkVarValid($tag,'id')) {
            $error='';
            if ($this->checkVarValid($tag, 'error')) {
                $error=$this->parseError($tag['error']);
            }
            $parseId=$this->parseVar($tag['id']);
            $this->_options['archiveCache']=$parseId;
            $parseStr.='<?php $_id='.$parseId.';  if(false==isset($_arc[$_id])){ $_dao=D(\'Archive\');$_arc[$_id]=$_dao->field(\'a.*,ac.content,u.realname\')->where(\'a.id=\'.$_id)->table(\''.$this->_tablePrefix.'archive a\')->join(\''.$this->_tablePrefix.'archive_content ac on ac.archive=a.id\')->join(\''.$this->_tablePrefix.'user u on u.id=a.pubID\')->find(); if(false===isset($_arc[$_id])){ ';
            $parseStr.=isset($error)?'echo \'\';':$error;
            $parseStr.=' }else{ ';
            $parseStr.=($this->checkVarValid($tag,'updateclick'))?' $_dao->setInc(\'click\',\'id=\'.$_id);$_arc[$_id][\'click\']=intval($_arc[$_id][\'click\'])+1;':'echo \'\';';
            $parseStr.=' }} ?>';
        }
        $parseStr.='<?php $_arcdata=$_arc['.$this->_options['archiveCache'].'];if(isset($_arcdata)){ ?>';
        if($this->checkVarValid($tag, 'field')){
            $source='stripcslashes($_arcdata[\''.$tag['field'].'\'])';
            if($this->checkVarValid($tag, 'func')){
                $func=$tag['func'];
                $pos=strpos($func,'=');
                $function=substr($func,0,$pos);
                $args=str_replace('###',$source,substr($func,$pos+1));
                $parseStr.="<?php echo $function($args);?>";
            }else{
                $parseStr.='<?php echo '.$source.';?>';
            }
        }
        return $parseStr.'<?php } ?>';
    }


    /**
     *　尝试解析属性值中的变量
     */
    private function parseVar($var){
        $cache='cache_'.md5($var);
        if (array_key_exists($cache, $this->_options)) {
            return $this->_options[$cache];
        }
        $str='';
        if ('$'===substr($var, 0, 1)) {
            $args=split('-',$var);
            $type=$args[0];
            if ('$archive'===$type) {
                $str.='$_arc['.$this->parseTpQuickOutput($args[1]).']';
            }
            $str.='[\''.$args[2].'\']';
        }else{
            $str.=$this->parseTpQuickOutput($var);
        }
        $this->_options[$cache] = $str;
        return $str;
    }

    /**
     * 解析TP模板中的快捷输出
     */
    public  function parseTpQuickOutput($var) {
        $flag=substr($var,0,1);
        $varname=substr($var,1);
        if('.'===$flag){    //Get variable
            return '$_GET[\''.$varname.'\']';
        }else if('^'===$flag){  //POST Variable
            return '$_POST[\''.$varname.'\']';
        }else if('@'===$flag){  //Session Variable
            return '$_SESSION[\''.$varname.'\']';
        }else{
            return '"'.$var.'"';
        }
    }

    private function checkVarValid($tag,$key) {
        if (array_key_exists($key, $tag) && ''!=$tag[$key] ) {
            return true;
        }
        return false;
    }

    private function parseError($error) {
        if(isset($error) && ''!=$error){
            return 'echo \'<script type="text/javascript" src="'.__APP__.'/../Tpl/default/ui/showError.js"></script><script type="text/javascript">showError("'.$error.'","'.__APP__.'")</script>\';';
        }
        return false;;
    }

}